import jwt from 'jsonwebtoken';
import jwtConfig from '@/config/jwt';

/**
 * 用户信息接口
 */
export interface UserInfo {
	userId: number;
	userName: string;
	roles: string[];
	permissions: string[];
	deptName?: string; // 新增此行
}

/**
 * JWT工具类
 * 提供JWT令牌的生成、验证和解码功能
 */
export default class JwtUtil {
  /**
   * 生成JWT令牌
   * @param userInfo 用户信息
   * @returns 生成的令牌
   */
  public static generateToken(userInfo: UserInfo): string {
    const options: jwt.SignOptions = {
			expiresIn: jwtConfig.expiresIn,
		} as jwt.SignOptions;
    return jwt.sign(userInfo, jwtConfig.secret as jwt.Secret, options);
  }

  /**
   * 生成刷新令牌（有效期更长）
   * @param userInfo 用户信息
   * @returns 生成的刷新令牌
   */
  public static generateRefreshToken(userInfo: UserInfo): string {
    // 刷新令牌有效期设为访问令牌的7倍
    const refreshExpiresIn = this.calculateRefreshTokenExpiry(jwtConfig.expiresIn);
    const options: jwt.SignOptions = {
			expiresIn: refreshExpiresIn,
		} as jwt.SignOptions;
    return jwt.sign(userInfo, jwtConfig.secret as jwt.Secret, options);
  }

  /**
   * 验证令牌
   * @param token 令牌
   * @returns 解码后的用户信息
   */
  public static verifyToken(token: string): UserInfo | null {
    try {
      return jwt.verify(token, jwtConfig.secret as jwt.Secret) as UserInfo;
    } catch (error) {
      return null;
    }
  }

  /**
   * 解码令牌（不验证有效性）
   * @param token 令牌
   * @returns 解码后的用户信息
   */
  public static decodeToken(token: string): UserInfo | null {
    try {
      return jwt.decode(token) as UserInfo;
    } catch (error) {
      return null;
    }
  }

  /**
   * 检查令牌是否过期
   * @param token 令牌
   * @returns 是否过期
   */
  public static isTokenExpired(token: string): boolean {
    try {
      const decoded = jwt.decode(token) as { exp: number };
      if (!decoded || typeof decoded.exp !== 'number') {
        return true;
      }
      
      const currentTime = Math.floor(Date.now() / 1000);
      return decoded.exp < currentTime;
    } catch (error) {
      return true;
    }
  }

  /**
   * 获取令牌过期时间
   * @param token JWT令牌
   * @returns 过期的Unix时间戳，如果令牌无效则返回null
   */
  public static getExpirationTime(token: string): number | null {
    try {
      const decoded = jwt.decode(token) as { exp: number };
      return decoded?.exp || null;
    } catch (error) {
      return null;
    }
  }

  /**
   * 计算刷新令牌的过期时间
   * @param accessTokenExpiry 访问令牌过期时间
   * @returns 刷新令牌过期时间
   */
  private static calculateRefreshTokenExpiry(accessTokenExpiry: string): string {
    // 解析访问令牌过期时间，如 '24h', '30m', '2d' 等
    const match = accessTokenExpiry.match(/^(\d+)([smhd])$/);
    if (!match) {
      // 默认为7天
      return '7d';
    }

    const [, value, unit] = match;
    const numValue = parseInt(value, 10);

    // 根据单位计算刷新令牌过期时间（是访问令牌的7倍）
    switch (unit) {
      case 's':
        return `${numValue * 7}s`;
      case 'm':
        return `${numValue * 7}m`;
      case 'h':
        return `${numValue * 7}h`;
      case 'd':
        return `${numValue * 7}d`;
      default:
        return '7d';
    }
  }
} 